﻿#region

using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Vin.Extension;
using Vin.Tool.AspNetCore.Singleton;
using Vin.Tool.Core.AssemblyCategory;

#endregion

namespace Vin.DependencyInjection.Core.Extension;

public static class VinExtensionExtension
{
    private static readonly List<IVinExtension?> VinExtensionList;

    private static readonly List<IVinApiExtension?> VinApiExtensionList;

    private static readonly List<Type> VinMiddlewareExtensionList;
    
    private static List<T?> GetExtensions<T>() where T : class
    {
        return AssemblyTool.GetTypes<T>()
            // 获取Attribute
            .Select(m => new
            {
                Type = m,
                Order = m.GetCustomAttribute<OrderAttribute>()?.Order ?? float.MaxValue
            })
            .OrderBy(m => m.Order)
            .Select(m => Activator.CreateInstance(m.Type) as T)
            .ToList();
    }

    static VinExtensionExtension()
    {
        VinExtensionList = GetExtensions<IVinExtension>();
        VinApiExtensionList = GetExtensions<IVinApiExtension>();
        VinMiddlewareExtensionList = AssemblyTool.GetTypes<IVinBeforeMiddlewareExtension>()
            // 获取Attribute
            .Select(m => new
            {
                Type = m,
                Order = m.GetCustomAttribute<OrderAttribute>()?.Order ?? float.MaxValue
            })
            .OrderBy(m => m.Order)
            .Select(m => m.Type)
            .ToList();

        // VinExtensionList = AssemblyTool.GetTypes<IVinExtension>()
        //     // 获取Attribute
        //     .Select(m => new
        //     {
        //         Type = m,
        //         Order = m.GetCustomAttribute<OrderAttribute>()?.Order ?? float.MaxValue
        //     })
        //     .OrderBy(m => m.Order)
        //     .Select(m => Activator.CreateInstance(m.Type) as IVinExtension)
        //     .ToList();
        // VinApiExtensionList = AssemblyTool.GetTypes<IVinApiExtension>()
        //     // 获取Attribute
        //     .Select(m => new
        //     {
        //         Type = m,
        //         Order = m.GetCustomAttribute<OrderAttribute>()?.Order ?? float.MaxValue
        //     })
        //     .OrderBy(m => m.Order)
        //     .Select(m => Activator.CreateInstance(m.Type) as IVinApiExtension)
        //     .ToList();
    }
    
    public static void AddVinExtension(this IHostApplicationBuilder builder)
    {
        foreach (var instance in VinExtensionList)
        {
            instance?.AddVinExtension(builder);
        }

        foreach (var instance in VinApiExtensionList)
        {
            instance?.AddVinExtension(builder);
        }
    }
    

    public static void AddVinExtension(this IServiceCollection services)
    {
        foreach (var instance in VinExtensionList)
        {
            instance?.AddVinExtension(services);
        }

        foreach (var instance in VinApiExtensionList)
        {
            if (instance != null)
            {
                VinApp.MvcBuilder.AddApplicationPart(instance.GetType().Assembly);
            }

            instance?.AddVinExtension(services);
        }
    }
}